{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e49f1e0d",
   "metadata": {},
   "source": [
    "# GigaChat\n",
    "\n",
    "В этом файле показано, как можно работать с GigaChat.\n",
    "\n",
    "Для начала работы вам нужно будет получить ключи доступа для работы с GigaChat. Подробнее об этом вы можете прочитать в [этом документе](docs/extras/integrations/chat/README.md)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "522686de",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from langchain.chat_models import GigaChat\n",
    "from langchain.prompts.chat import (\n",
    "    AIMessagePromptTemplate,\n",
    "    ChatPromptTemplate,\n",
    "    HumanMessagePromptTemplate,\n",
    "    SystemMessagePromptTemplate,\n",
    ")\n",
    "from langchain.schema import AIMessage, HumanMessage, SystemMessage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "62e0dbc3",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "chat = GigaChat(credentials=...)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e5fe97e",
   "metadata": {},
   "source": [
    "В ячейке выше показано, как подключить к GigaChat. Вы также можете хранить авторизационные данные в переменной окружения `GIGACHAT_CREDENTIALS`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ce16ad78-8e6f-48cd-954e-98be75eb5836",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='I love programming.', additional_kwargs={}, example=False)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages = [\n",
    "    SystemMessage(\n",
    "        content=\"Ты полезный ассистент, который умеет переводить русский на английский.\"\n",
    "    ),\n",
    "    HumanMessage(content=\"Переведи это предложение. Я люблю программирование.\"),\n",
    "]\n",
    "chat(messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "778f912a-66ea-4a5d-b3de-6c7db4baba26",
   "metadata": {},
   "source": [
    "Вы можете использовать шаблонизацию с помощью `MessagePromptTemplate`. Вы можете создать `ChatPromptTemplate` из одного или нескольких `MessagePromptTemplates`. Вы можете использовать метод `format_prompt` класса `ChatPromptTemplate` — это возвращает `PromptValue`, который вы можете преобразовать в строку или объект сообщения, в зависимости от того, хотите ли вы использовать отформатированное значение как входные данные для модели llm или чат-модели.\n",
    "\n",
    "Для удобства есть метод `from_template`, предоставленный в шаблоне. Если вы хотите использовать этот шаблон, это будет выглядеть примерно так:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "180c5cc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "template = \"Ты полезный ассистент, который умеет переводить {input_language} на {output_language}.\"\n",
    "system_message_prompt = SystemMessagePromptTemplate.from_template(template)\n",
    "human_template = \"{text}\"\n",
    "human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "fbb043e6",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='Я люблю программирование.', additional_kwargs={}, example=False)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chat_prompt = ChatPromptTemplate.from_messages(\n",
    "    [system_message_prompt, human_message_prompt]\n",
    ")\n",
    "\n",
    "# get a chat completion from the formatted messages\n",
    "chat(\n",
    "    chat_prompt.format_prompt(\n",
    "        input_language=\"английский\",\n",
    "        output_language=\"русский\",\n",
    "        text=\"Translate this sentense. I love programming.\",\n",
    "    ).to_messages()\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f4d053a",
   "metadata": {},
   "source": [
    "## Потоковое получение ответа\n",
    "GigaChat может возвращать промежуточные результаты генерации ответа пользователю.\n",
    "\n",
    "Для этого нужно создать класс-наследник `BaseCallbackHandler`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "6dc22953",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.callbacks.base import BaseCallbackHandler\n",
    "\n",
    "\n",
    "class StreamHandler(BaseCallbackHandler):\n",
    "    def __init__(self, initial_text=\"\"):\n",
    "        pass\n",
    "\n",
    "    def on_llm_new_token(self, token: str, **kwargs) -> None:\n",
    "        print(f\"{token} -\", end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a95a48f",
   "metadata": {},
   "source": [
    "Гигачат нужно инициализировать в режиме стриминга:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "521a4b03",
   "metadata": {},
   "outputs": [],
   "source": [
    "chat = GigaChat(credentials=..., streaming=True, callbacks=[StreamHandler()])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "884a11f7",
   "metadata": {},
   "source": [
    "Теперь, при вызове генерации можно увидеть, как ответ модели последовательно выводится пользователю."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "39033b38",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "«Евгений Онегин» — роман в стихах, написанный Александром Сергеевичем Пушкиным. Произведение было написано в период с 1823 по 1831 годы и впервые опубликовано в журнале «Современник».\n",
      "\n",
      "Роман рассказывает о жизни двух друзей — Евгения Онегина и Владимира Ленского. Они проводят много - времени - вместе -, - де -лятся - своими - мы -сля -ми - и - чувства -ми -. - Однако - между - ними - возникает - конфликт - из -- -за - любви - к - одной - женщи -не - — - Оль -ге - Ла -ри -ной -. - В - результате - ду -э -ли - Владимир - Л -ен -ский - поги -ба -ет -, - а - Евгений - О -не -гин - поки -дает - Россию -. -\n",
      " -\n",
      " -Ч -ере -з - несколько - лет - Евгений - возвра -щается - в - Россию - и - начинает - уха -живать - за - Оль -гой -. - Он - призна -ется - ей - в - любви -, - но - она - отвер -гает - его -. - В - конце - концов - Ольга - выходит - заму -ж - за - князя - Гре -чина -. -\n",
      " -\n",
      " -О -не -гин - разоча -рован - и - у -яз -влен - таким - ис -ходом - событий -. - Он - решает - поки -нуть - Россию - нав -се -гда - и - отправля -ется - в - Евро -пу -. - -"
     ]
    },
    {
     "data": {
      "text/plain": [
       "AIMessageChunk(content='«Евгений Онегин» — роман в стихах, написанный Александром Сергеевичем Пушкиным. Произведение было написано в период с 1823 по 1831 годы и впервые опубликовано в журнале «Современник».\\n\\nРоман рассказывает о жизни двух друзей — Евгения Онегина и Владимира Ленского. Они проводят много времени вместе, делятся своими мыслями и чувствами. Однако между ними возникает конфликт из-за любви к одной женщине — Ольге Лариной. В результате дуэли Владимир Ленский погибает, а Евгений Онегин покидает Россию.\\n\\nЧерез несколько лет Евгений возвращается в Россию и начинает ухаживать за Ольгой. Он признается ей в любви, но она отвергает его. В конце концов Ольга выходит замуж за князя Гречина.\\n\\nОнегин разочарован и уязвлен таким исходом событий. Он решает покинуть Россию навсегда и отправляется в Европу.')"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chat([HumanMessage(content=\"Напиши краткое содержание романа Евгений Онегин\")])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
